x86: rdtsc emulation (PV and HVM) must be monotonically increasing
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 2 Sep 2009 10:39:02 +0000 (11:39 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 2 Sep 2009 10:39:02 +0000 (11:39 +0100)
The Intel SDM (section 18.10) clearly states that rdtsc
returns a "monotonically increasing unique value".
Current emulation code for rdtsc (both PV and HVM) returns
only a monotonically-non-decreasing (non-unique) value,
so ensure stale value is always incremented.

Signed-off-by: Dan Magenheimer <dan.magenheimer@oracle.com>
xen/arch/x86/hvm/vpt.c
xen/arch/x86/time.c

index eb24f5d39819a74241a1f0feacb8f5afffe47f9f..0cb180ceba92d8005b4bc8ed28437edd78d0a1aa 100644 (file)
@@ -47,10 +47,10 @@ u64 hvm_get_guest_time(struct vcpu *v)
 
     spin_lock(&pl->pl_time_lock);
     now = get_s_time() + pl->stime_offset;
-    if ( (int64_t)(now - pl->last_guest_time) >= 0 )
+    if ( (int64_t)(now - pl->last_guest_time) > 0 )
         pl->last_guest_time = now;
     else
-        now = pl->last_guest_time;
+        now = ++pl->last_guest_time;
     spin_unlock(&pl->pl_time_lock);
 
     return now + v->arch.hvm_vcpu.stime_offset;
index 5292a3b9a1245ee24c7c0e0b2f477dc4f166183c..f458a2976658eaf73f8f0b7edd61d839ce420d66 100644 (file)
@@ -1454,10 +1454,10 @@ void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs)
         rdtsc_usercount++;
         spin_lock(&v->domain->arch.vtsc_lock);
         now = get_s_time() + v->domain->arch.vtsc_stime_offset;
-        if ( (int64_t)(now - v->domain->arch.vtsc_last) >= 0 )
+        if ( (int64_t)(now - v->domain->arch.vtsc_last) > 0 )
             v->domain->arch.vtsc_last = now;
         else
-            now = v->domain->arch.vtsc_last;
+            now = ++v->domain->arch.vtsc_last;
         spin_unlock(&v->domain->arch.vtsc_lock);
         regs->eax = (uint32_t)now;
         regs->edx = (uint32_t)(now >> 32);